﻿using Microsoft.Extensions.DependencyModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using System.Text;
using System.Threading.Tasks;

namespace Framework.Core.Util
{
	/// <summary>
	/// 程序集工具
	/// </summary>
	public static class AssemblyUtil
	{
		/// <summary>
		/// 所有程序集缓存对象
		/// </summary>
		/// <returns></returns>
		private static readonly List<Assembly> _assemblyList = new();

		/// <summary>
		/// 扫描所有程序集
		/// </summary>
		/// <param name="assemblyNames">需要扫描的程序集名称,可传入关键字,模糊匹配</param>
		/// <returns></returns>
		static IEnumerable<Assembly> ScanAllAssembly(params string[]? assemblyNames)
		{
			// 参考：https://www.cnblogs.com/yanglang/p/6866165.html

			var result = new List<Assembly>();
			var libs = DependencyContext.Default?.CompileLibraries.Where(lib => !lib.Serviceable && lib.Type != "package");
			if (libs == null)
			{
				throw new ArgumentNullException(nameof(libs));
			}

			foreach (var lib in libs)
			{
				var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(lib.Name));
				result.Add(assembly);
			}
			return result;
		}

		/// <summary>
		/// 获取所有的 程序集
		/// </summary>
		/// <param name="assemblyNames">需要扫描的程序集名称,可传入关键字,模糊匹配</param>
		/// <returns></returns>
		public static IEnumerable<Assembly> GetAssemblyList(params string[]? assemblyNames)
		{
			if (_assemblyList.Count == 0)
			{
				_assemblyList.AddRange(ScanAllAssembly(assemblyNames));
			}

			if (assemblyNames != null && assemblyNames.Length > 0)
			{
				return _assemblyList.Where(w => assemblyNames.Where(s => !string.IsNullOrWhiteSpace(w.FullName)).Any(s => w.FullName!.Contains(s)));
			}

			return _assemblyList;
		}
	}
}
